from mininet.topo import Topo
from mininet.net import Mininet
from mininet.node import OVSBridge, Controller, Node,OVSSwitch,findController

from optparse import OptionParser
from mininet.log import setLogLevel
from mininet.cli import CLI
import time, os

class LinuxRouter(Node):
    "A Node with IP forwarding enabled."

    def config(self, **params):
        super(LinuxRouter, self).config(**params)
        # Enable forwarding on the router
        self.cmd('sysctl net.ipv4.ip_forward=1')
        # self.cmd('socat tcp-l:2620,fork,reuseaddr tcp:11.0.0.254:2620 &')

    def terminate(self):
        self.cmd('sysctl net.ipv4.ip_forward=0')
        self.cmd('pkill lt-zebra')
        self.cmd('pkill lt-ospf')
        super(LinuxRouter, self).terminate()
# predivtive routing 2017
# zhanghong 2020 hotnet
class simple(Topo):
    def __init__(self, k=2):
        Topo.__init__(self)
        # c = self.addHost('c', ip='11.0.0.254/24', defaultRoute='via 11.0.0.254')
        # s0 = self.addSwitch('s0', cls=OVSBridge)
        # self.addLink(c, s0)
        # h1 = self.addHost('h1', ip='12.0.0.1/24', defaultRoute='via 12.0.0.2')
        h1 = self.addHost('h1', ip=None)
        # self.addLink(h1, c)
        # r1 = self.addNode('r1', cls=LinuxRouter, ip='10.0.3.1/24')
        # r2 = self.addNode('r2', cls=LinuxRouter, ip='10.0.3.2/24')
        r1 = self.addNode('r1', cls=LinuxRouter, ip=None)
        r2 = self.addNode('r2', cls=LinuxRouter, ip=None)
        r3 = self.addNode('r3', cls=LinuxRouter, ip=None)
        # self.addLink(h2, c)
        h2 = self.addHost('h2', ip=None)
        # self.addLink(h3, c)
        self.addLink(h1, r1, params1={'ip':'13.0.0.1/24'}, params2={'ip': '13.0.0.2/24'})
        self.addLink(r1, r2, params1={'ip':'12.0.0.1/24'}, params2={'ip': '12.0.0.2/24'})
        self.addLink(r2, r3, params1={'ip':'12.0.1.1/24'}, params2={'ip': '12.0.1.2/24'})
        self.addLink(h2, r3, params1={'ip':'13.0.1.1/24'}, params2={'ip': '13.0.1.2/24'})
        # h2.cmd('/home/gd/frr/zebra/zebra -i /tmp/zebra.pid -f tmp/zebra.conf -d')
        # h2.cmd('/home/gd/frr/ospfd/ospfd -i /tmp/ospf.pid -f tmp/ospfd.conf -d')

class Mycli(CLI, object):
    def __init__(self, net):
        super(Mycli, self).__init__(net)

    def do_link(self, line):
        super(Mycli, self).do_link(line)

    def do_init_ospf(self, line):
        for node in self.mn.topo.nodes():
            if 'h' in node:
                continue
            net.get(node).cmd('/home/gd/frr/zebra/zebra -i /tmp/zebra-%s.pid -f r1/%s.conf -N %s -M fpm:protobuf -d' % (node, node, node))
            net.get(node).cmd('/home/gd/frr/ospfd/ospfd -i /tmp/ospfd-%s.pid -f r1/%s.conf -N %s -d' % (node, node, node))

setLogLevel('info')
topo = simple()
net = Mininet(topo=topo, controller=None)
net.start()
# r1=net.getNodeByName('r1')
# r2=net.getNodeByName('r2')
# r1.cmd('/home/gd/frr/zebra/zebra -N r1 -i /tmp/zebra-r1.pid -f r1/zebra.conf -d')
# r1.cmd('/home/gd/frr/ospfd/ospfd -N r1 -i /tmp/ospfd-r1.pid -f r1/ospfd.conf -d')
# r2.cmd('/home/gd/frr/zebra/zebra -N r2 -i /tmp/zebra-r2.pid -f r1/zebra.conf -d')
# r2.cmd('/home/gd/frr/ospfd/ospfd -N r2 -i /tmp/ospfd-r2.pid -f r1/ospfd.conf -d')
Mycli(net)
net.stop()
os.system('pkill ospfd')
os.system('pkill zebra')
